{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "30327e3a"
      },
      "source": [
        "# 🚀 Exploring the openai-agents Library with Gemini\n",
        "This notebook shows how to use the openai-agents library with Gemini API to build conversational agents—covering two execution methods"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wd12XkqwSRxc"
      },
      "source": [
        "# 📦 installation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "id": "8U2DuZP0_1Iu"
      },
      "outputs": [],
      "source": [
        "!pip install -Uq openai-agents"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jL-reb6RR_H6"
      },
      "source": [
        "# 📦 Imports"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "OE_-gMwUDw8b"
      },
      "outputs": [],
      "source": [
        "import nest_asyncio\n",
        "nest_asyncio.apply()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MywTysH-Rn2h"
      },
      "source": [
        "# 📦 Imports"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "id": "dvNo75PtD5YL"
      },
      "outputs": [],
      "source": [
        "from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel, set_tracing_disabled"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uO3deejXRZw8"
      },
      "source": [
        "# 🔐 Step 1: Setup for Api Keys"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "9p1ynoc0EDCx"
      },
      "outputs": [],
      "source": [
        "from google.colab import userdata\n",
        "gemini_api_key = userdata.get(\"GEMINI_API_KEY\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "S4GITaFOP526"
      },
      "source": [
        "# 🌐  Step 2: Client Setup for Connecting to **Gemini**"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "id": "IofWknGLEHHI"
      },
      "outputs": [],
      "source": [
        "# Tracing disabled\n",
        "set_tracing_disabled(disabled=True)\n",
        "\n",
        "# 1. Which LLM Service?\n",
        "external_client: AsyncOpenAI = AsyncOpenAI(\n",
        "    api_key=gemini_api_key,\n",
        "    base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n",
        ")\n",
        "\n",
        "# 2. Which LLM Model?\n",
        "llm_model: OpenAIChatCompletionsModel = OpenAIChatCompletionsModel(\n",
        "    model=\"gemini-2.5-flash\",\n",
        "    openai_client=external_client\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Upg62mcUJUB4"
      },
      "source": [
        "# 💬  Step 3 Running Agent Synchronously"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "4QgfJqHZJV_M",
        "outputId": "f98b8c45-35a5-4779-da79-e5368af26e9e"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "CALLING AGENT\n",
            "\n",
            "Learning math is absolutely fundamental for anyone seriously pursuing a career in AI, particularly for those who want to do more than just use existing tools. Here's why it's crucial for AI agents:\n",
            "\n",
            "1.  **The Language of AI is Mathematics:**\n",
            "    *   **Algorithms are Mathematical Constructs:** Every AI algorithm, from simple linear regression to complex deep neural networks, is fundamentally a mathematical model. Understanding the underlying math allows you to comprehend how these algorithms work, their limitations, and how to optimize them.\n",
            "    *   **Data Representation:** Data (images, text, audio, sensor readings) is represented mathematically as vectors, matrices, and tensors. Linear algebra is the foundation for manipulating and transforming this data.\n",
            "\n",
            "2.  **Core Mathematical Disciplines and Their AI Applications:**\n",
            "\n",
            "    *   **Linear Algebra:**\n",
            "        *   **Data Representation:** Vectors for word embeddings, matrices for images, tensors for video and complex neural network layers.\n",
            "        *   **Transformations:** Rotations, scaling, translations vital for computer vision, robotics, and graph neural networks.\n",
            "        *   **Dimensionality Reduction:** Techniques like PCA (Principal Component Analysis) are heavily based on eigenvalues and eigenvectors.\n",
            "        *   **Neural Networks:** Matrix multiplications are the core operation in every layer of a neural network. Understanding them is key to grasping how information flows and is transformed.\n",
            "\n",
            "    *   **Calculus (Differential & Integral):**\n",
            "        *   **Optimization:** This is arguably the *most critical* application. AI models learn by minimizing a \"loss function\" (an error metric). Gradient descent, the primary optimization algorithm, relies on derivatives to find the direction of steepest descent.\n",
            "        *   **Backpropagation:** The algorithm used to train neural networks is an application of the chain rule from calculus. Understanding it is essential for debugging and designing new architectures.\n",
            "        *   **Understanding Change:** Derivatives help you understand how a small change in one parameter affects the output, crucial for model interpretation and sensitivity analysis.\n",
            "\n",
            "    *   **Probability & Statistics:**\n",
            "        *   **Uncertainty Modeling:** AI agents often operate in uncertain environments. Probability theory is used to quantify and manage this uncertainty (e.g., Bayesian networks, Markov models).\n",
            "        *   **Data Analysis & Interpretation:** Understanding distributions, variance, correlation, and hypothesis testing is vital for pre-processing data, feature engineering, and evaluating model performance.\n",
            "        *   **Decision Making:** Many AI agents make decisions based on probabilistic outcomes (e.g., Reinforcement Learning often involves probabilities of actions).\n",
            "        *   **Machine Learning Algorithms:** Many algorithms (e.g., Naive Bayes, Gaussian Mixture Models, Hidden Markov Models) are explicitly statistical.\n",
            "\n",
            "    *   **Discrete Mathematics (Logic, Graph Theory, Combinatorics):**\n",
            "        *   **Logic and Knowledge Representation:** Foundation for symbolic AI, expert systems, and knowledge graphs. Crucial for agents that need to reason and make logical deductions.\n",
            "        *   **Algorithms and Complexity:** Understanding graph theory is vital for search algorithms (e.g., A*, BFS, DFS in pathfinding or state-space search), representing relationships in data, and neural network architectures. Combinatorics helps understand the complexity of problems and possible solutions.\n",
            "        *   **Game Theory:** Important for multi-agent systems, competitive AI, and understanding strategic interactions.\n",
            "\n",
            "    *   **Optimization Theory:**\n",
            "        *   While often a blend of calculus and linear algebra, it's a field in itself. It's about finding the \"best\" solution given constraints. This is central to training all machine learning models, resource allocation, and planning for AI agents.\n",
            "\n",
            "3.  **Beyond Just Using Libraries:**\n",
            "    *   **Debugging and Troubleshooting:** When your model isn't working as expected, a strong math foundation helps you identify *why*. Is it an issue with the gradient, a poorly chosen loss function, or an incorrect data transformation?\n",
            "    *   **Developing New Algorithms:** If you want to push the boundaries of AI, you need to be able to read and understand research papers, which are heavily mathematical. Creating novel solutions requires deriving and implementing new mathematical models.\n",
            "    *   **Interpreting Results:** Understanding the statistical significance of results, the meaning of confidence intervals, and the limitations of your model requires mathematical insight.\n",
            "    *   **Customization and Adaptation:** Pre-built libraries are great, but real-world problems often require custom solutions. Math empowers you to adapt existing algorithms or build new ones from scratch.\n",
            "    *   **Critical Thinking and Problem Solving:** Math trains your brain to think logically, break down complex problems, and approach them systematically – skills invaluable in any AI role.\n",
            "\n",
            "In essence, math isn't just a prerequisite; it's the toolbox, the blueprint, and the language that allows you to truly understand, build, and innovate with AI agents. Without it, you're merely a mechanic assembling parts without understanding the engineering.\n"
          ]
        }
      ],
      "source": [
        "math_agent: Agent = Agent(name=\"MathAgent\",\n",
        "                     instructions=\"You are a helpful math assistant.\",\n",
        "                     model=llm_model) # gemini-2.5 as agent brain - chat completions\n",
        "\n",
        "result: Runner = Runner.run_sync(math_agent, \"why learn math for AI Agents?\")\n",
        "\n",
        "print(\"\\nCALLING AGENT\\n\")\n",
        "print(result.final_output)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "Z5oKiMPbd7BC",
        "outputId": "7bbe0ffe-9854-41a4-f729-c186167ab045"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "RunResult(input='why learn math for AI Agents?', new_items=[MessageOutputItem(agent=Agent(name='MathAgent', handoff_description=None, tools=[], mcp_servers=[], mcp_config={}, instructions='You are a helpful math assistant.', prompt=None, handoffs=[], model=<agents.models.openai_chatcompletions.OpenAIChatCompletionsModel object at 0x78430578a890>, model_settings=ModelSettings(temperature=None, top_p=None, frequency_penalty=None, presence_penalty=None, tool_choice=None, parallel_tool_calls=None, truncation=None, max_tokens=None, reasoning=None, metadata=None, store=None, include_usage=None, response_include=None, extra_query=None, extra_body=None, extra_headers=None, extra_args=None), input_guardrails=[], output_guardrails=[], output_type=None, hooks=None, tool_use_behavior='run_llm_again', reset_tool_choice=True), raw_item=ResponseOutputMessage(id='__fake_id__', content=[ResponseOutputText(annotations=[], text='Learning math is absolutely fundamental for anyone seriously pursuing a career in AI, particularly for those who want to do more than just use existing tools. Here\\'s why it\\'s crucial for AI agents:\\n\\n1.  **The Language of AI is Mathematics:**\\n    *   **Algorithms are Mathematical Constructs:** Every AI algorithm, from simple linear regression to complex deep neural networks, is fundamentally a mathematical model. Understanding the underlying math allows you to comprehend how these algorithms work, their limitations, and how to optimize them.\\n    *   **Data Representation:** Data (images, text, audio, sensor readings) is represented mathematically as vectors, matrices, and tensors. Linear algebra is the foundation for manipulating and transforming this data.\\n\\n2.  **Core Mathematical Disciplines and Their AI Applications:**\\n\\n    *   **Linear Algebra:**\\n        *   **Data Representation:** Vectors for word embeddings, matrices for images, tensors for video and complex neural network layers.\\n        *   **Transformations:** Rotations, scaling, translations vital for computer vision, robotics, and graph neural networks.\\n        *   **Dimensionality Reduction:** Techniques like PCA (Principal Component Analysis) are heavily based on eigenvalues and eigenvectors.\\n        *   **Neural Networks:** Matrix multiplications are the core operation in every layer of a neural network. Understanding them is key to grasping how information flows and is transformed.\\n\\n    *   **Calculus (Differential & Integral):**\\n        *   **Optimization:** This is arguably the *most critical* application. AI models learn by minimizing a \"loss function\" (an error metric). Gradient descent, the primary optimization algorithm, relies on derivatives to find the direction of steepest descent.\\n        *   **Backpropagation:** The algorithm used to train neural networks is an application of the chain rule from calculus. Understanding it is essential for debugging and designing new architectures.\\n        *   **Understanding Change:** Derivatives help you understand how a small change in one parameter affects the output, crucial for model interpretation and sensitivity analysis.\\n\\n    *   **Probability & Statistics:**\\n        *   **Uncertainty Modeling:** AI agents often operate in uncertain environments. Probability theory is used to quantify and manage this uncertainty (e.g., Bayesian networks, Markov models).\\n        *   **Data Analysis & Interpretation:** Understanding distributions, variance, correlation, and hypothesis testing is vital for pre-processing data, feature engineering, and evaluating model performance.\\n        *   **Decision Making:** Many AI agents make decisions based on probabilistic outcomes (e.g., Reinforcement Learning often involves probabilities of actions).\\n        *   **Machine Learning Algorithms:** Many algorithms (e.g., Naive Bayes, Gaussian Mixture Models, Hidden Markov Models) are explicitly statistical.\\n\\n    *   **Discrete Mathematics (Logic, Graph Theory, Combinatorics):**\\n        *   **Logic and Knowledge Representation:** Foundation for symbolic AI, expert systems, and knowledge graphs. Crucial for agents that need to reason and make logical deductions.\\n        *   **Algorithms and Complexity:** Understanding graph theory is vital for search algorithms (e.g., A*, BFS, DFS in pathfinding or state-space search), representing relationships in data, and neural network architectures. Combinatorics helps understand the complexity of problems and possible solutions.\\n        *   **Game Theory:** Important for multi-agent systems, competitive AI, and understanding strategic interactions.\\n\\n    *   **Optimization Theory:**\\n        *   While often a blend of calculus and linear algebra, it\\'s a field in itself. It\\'s about finding the \"best\" solution given constraints. This is central to training all machine learning models, resource allocation, and planning for AI agents.\\n\\n3.  **Beyond Just Using Libraries:**\\n    *   **Debugging and Troubleshooting:** When your model isn\\'t working as expected, a strong math foundation helps you identify *why*. Is it an issue with the gradient, a poorly chosen loss function, or an incorrect data transformation?\\n    *   **Developing New Algorithms:** If you want to push the boundaries of AI, you need to be able to read and understand research papers, which are heavily mathematical. Creating novel solutions requires deriving and implementing new mathematical models.\\n    *   **Interpreting Results:** Understanding the statistical significance of results, the meaning of confidence intervals, and the limitations of your model requires mathematical insight.\\n    *   **Customization and Adaptation:** Pre-built libraries are great, but real-world problems often require custom solutions. Math empowers you to adapt existing algorithms or build new ones from scratch.\\n    *   **Critical Thinking and Problem Solving:** Math trains your brain to think logically, break down complex problems, and approach them systematically – skills invaluable in any AI role.\\n\\nIn essence, math isn\\'t just a prerequisite; it\\'s the toolbox, the blueprint, and the language that allows you to truly understand, build, and innovate with AI agents. Without it, you\\'re merely a mechanic assembling parts without understanding the engineering.', type='output_text', logprobs=None)], role='assistant', status='completed', type='message'), type='message_output_item')], raw_responses=[ModelResponse(output=[ResponseOutputMessage(id='__fake_id__', content=[ResponseOutputText(annotations=[], text='Learning math is absolutely fundamental for anyone seriously pursuing a career in AI, particularly for those who want to do more than just use existing tools. Here\\'s why it\\'s crucial for AI agents:\\n\\n1.  **The Language of AI is Mathematics:**\\n    *   **Algorithms are Mathematical Constructs:** Every AI algorithm, from simple linear regression to complex deep neural networks, is fundamentally a mathematical model. Understanding the underlying math allows you to comprehend how these algorithms work, their limitations, and how to optimize them.\\n    *   **Data Representation:** Data (images, text, audio, sensor readings) is represented mathematically as vectors, matrices, and tensors. Linear algebra is the foundation for manipulating and transforming this data.\\n\\n2.  **Core Mathematical Disciplines and Their AI Applications:**\\n\\n    *   **Linear Algebra:**\\n        *   **Data Representation:** Vectors for word embeddings, matrices for images, tensors for video and complex neural network layers.\\n        *   **Transformations:** Rotations, scaling, translations vital for computer vision, robotics, and graph neural networks.\\n        *   **Dimensionality Reduction:** Techniques like PCA (Principal Component Analysis) are heavily based on eigenvalues and eigenvectors.\\n        *   **Neural Networks:** Matrix multiplications are the core operation in every layer of a neural network. Understanding them is key to grasping how information flows and is transformed.\\n\\n    *   **Calculus (Differential & Integral):**\\n        *   **Optimization:** This is arguably the *most critical* application. AI models learn by minimizing a \"loss function\" (an error metric). Gradient descent, the primary optimization algorithm, relies on derivatives to find the direction of steepest descent.\\n        *   **Backpropagation:** The algorithm used to train neural networks is an application of the chain rule from calculus. Understanding it is essential for debugging and designing new architectures.\\n        *   **Understanding Change:** Derivatives help you understand how a small change in one parameter affects the output, crucial for model interpretation and sensitivity analysis.\\n\\n    *   **Probability & Statistics:**\\n        *   **Uncertainty Modeling:** AI agents often operate in uncertain environments. Probability theory is used to quantify and manage this uncertainty (e.g., Bayesian networks, Markov models).\\n        *   **Data Analysis & Interpretation:** Understanding distributions, variance, correlation, and hypothesis testing is vital for pre-processing data, feature engineering, and evaluating model performance.\\n        *   **Decision Making:** Many AI agents make decisions based on probabilistic outcomes (e.g., Reinforcement Learning often involves probabilities of actions).\\n        *   **Machine Learning Algorithms:** Many algorithms (e.g., Naive Bayes, Gaussian Mixture Models, Hidden Markov Models) are explicitly statistical.\\n\\n    *   **Discrete Mathematics (Logic, Graph Theory, Combinatorics):**\\n        *   **Logic and Knowledge Representation:** Foundation for symbolic AI, expert systems, and knowledge graphs. Crucial for agents that need to reason and make logical deductions.\\n        *   **Algorithms and Complexity:** Understanding graph theory is vital for search algorithms (e.g., A*, BFS, DFS in pathfinding or state-space search), representing relationships in data, and neural network architectures. Combinatorics helps understand the complexity of problems and possible solutions.\\n        *   **Game Theory:** Important for multi-agent systems, competitive AI, and understanding strategic interactions.\\n\\n    *   **Optimization Theory:**\\n        *   While often a blend of calculus and linear algebra, it\\'s a field in itself. It\\'s about finding the \"best\" solution given constraints. This is central to training all machine learning models, resource allocation, and planning for AI agents.\\n\\n3.  **Beyond Just Using Libraries:**\\n    *   **Debugging and Troubleshooting:** When your model isn\\'t working as expected, a strong math foundation helps you identify *why*. Is it an issue with the gradient, a poorly chosen loss function, or an incorrect data transformation?\\n    *   **Developing New Algorithms:** If you want to push the boundaries of AI, you need to be able to read and understand research papers, which are heavily mathematical. Creating novel solutions requires deriving and implementing new mathematical models.\\n    *   **Interpreting Results:** Understanding the statistical significance of results, the meaning of confidence intervals, and the limitations of your model requires mathematical insight.\\n    *   **Customization and Adaptation:** Pre-built libraries are great, but real-world problems often require custom solutions. Math empowers you to adapt existing algorithms or build new ones from scratch.\\n    *   **Critical Thinking and Problem Solving:** Math trains your brain to think logically, break down complex problems, and approach them systematically – skills invaluable in any AI role.\\n\\nIn essence, math isn\\'t just a prerequisite; it\\'s the toolbox, the blueprint, and the language that allows you to truly understand, build, and innovate with AI agents. Without it, you\\'re merely a mechanic assembling parts without understanding the engineering.', type='output_text', logprobs=None)], role='assistant', status='completed', type='message')], usage=Usage(requests=1, input_tokens=16, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=1024, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=2147), response_id=None)], final_output='Learning math is absolutely fundamental for anyone seriously pursuing a career in AI, particularly for those who want to do more than just use existing tools. Here\\'s why it\\'s crucial for AI agents:\\n\\n1.  **The Language of AI is Mathematics:**\\n    *   **Algorithms are Mathematical Constructs:** Every AI algorithm, from simple linear regression to complex deep neural networks, is fundamentally a mathematical model. Understanding the underlying math allows you to comprehend how these algorithms work, their limitations, and how to optimize them.\\n    *   **Data Representation:** Data (images, text, audio, sensor readings) is represented mathematically as vectors, matrices, and tensors. Linear algebra is the foundation for manipulating and transforming this data.\\n\\n2.  **Core Mathematical Disciplines and Their AI Applications:**\\n\\n    *   **Linear Algebra:**\\n        *   **Data Representation:** Vectors for word embeddings, matrices for images, tensors for video and complex neural network layers.\\n        *   **Transformations:** Rotations, scaling, translations vital for computer vision, robotics, and graph neural networks.\\n        *   **Dimensionality Reduction:** Techniques like PCA (Principal Component Analysis) are heavily based on eigenvalues and eigenvectors.\\n        *   **Neural Networks:** Matrix multiplications are the core operation in every layer of a neural network. Understanding them is key to grasping how information flows and is transformed.\\n\\n    *   **Calculus (Differential & Integral):**\\n        *   **Optimization:** This is arguably the *most critical* application. AI models learn by minimizing a \"loss function\" (an error metric). Gradient descent, the primary optimization algorithm, relies on derivatives to find the direction of steepest descent.\\n        *   **Backpropagation:** The algorithm used to train neural networks is an application of the chain rule from calculus. Understanding it is essential for debugging and designing new architectures.\\n        *   **Understanding Change:** Derivatives help you understand how a small change in one parameter affects the output, crucial for model interpretation and sensitivity analysis.\\n\\n    *   **Probability & Statistics:**\\n        *   **Uncertainty Modeling:** AI agents often operate in uncertain environments. Probability theory is used to quantify and manage this uncertainty (e.g., Bayesian networks, Markov models).\\n        *   **Data Analysis & Interpretation:** Understanding distributions, variance, correlation, and hypothesis testing is vital for pre-processing data, feature engineering, and evaluating model performance.\\n        *   **Decision Making:** Many AI agents make decisions based on probabilistic outcomes (e.g., Reinforcement Learning often involves probabilities of actions).\\n        *   **Machine Learning Algorithms:** Many algorithms (e.g., Naive Bayes, Gaussian Mixture Models, Hidden Markov Models) are explicitly statistical.\\n\\n    *   **Discrete Mathematics (Logic, Graph Theory, Combinatorics):**\\n        *   **Logic and Knowledge Representation:** Foundation for symbolic AI, expert systems, and knowledge graphs. Crucial for agents that need to reason and make logical deductions.\\n        *   **Algorithms and Complexity:** Understanding graph theory is vital for search algorithms (e.g., A*, BFS, DFS in pathfinding or state-space search), representing relationships in data, and neural network architectures. Combinatorics helps understand the complexity of problems and possible solutions.\\n        *   **Game Theory:** Important for multi-agent systems, competitive AI, and understanding strategic interactions.\\n\\n    *   **Optimization Theory:**\\n        *   While often a blend of calculus and linear algebra, it\\'s a field in itself. It\\'s about finding the \"best\" solution given constraints. This is central to training all machine learning models, resource allocation, and planning for AI agents.\\n\\n3.  **Beyond Just Using Libraries:**\\n    *   **Debugging and Troubleshooting:** When your model isn\\'t working as expected, a strong math foundation helps you identify *why*. Is it an issue with the gradient, a poorly chosen loss function, or an incorrect data transformation?\\n    *   **Developing New Algorithms:** If you want to push the boundaries of AI, you need to be able to read and understand research papers, which are heavily mathematical. Creating novel solutions requires deriving and implementing new mathematical models.\\n    *   **Interpreting Results:** Understanding the statistical significance of results, the meaning of confidence intervals, and the limitations of your model requires mathematical insight.\\n    *   **Customization and Adaptation:** Pre-built libraries are great, but real-world problems often require custom solutions. Math empowers you to adapt existing algorithms or build new ones from scratch.\\n    *   **Critical Thinking and Problem Solving:** Math trains your brain to think logically, break down complex problems, and approach them systematically – skills invaluable in any AI role.\\n\\nIn essence, math isn\\'t just a prerequisite; it\\'s the toolbox, the blueprint, and the language that allows you to truly understand, build, and innovate with AI agents. Without it, you\\'re merely a mechanic assembling parts without understanding the engineering.', input_guardrail_results=[], output_guardrail_results=[], context_wrapper=RunContextWrapper(context=None, usage=Usage(requests=1, input_tokens=16, input_tokens_details=InputTokensDetails(cached_tokens=0), output_tokens=1024, output_tokens_details=OutputTokensDetails(reasoning_tokens=0), total_tokens=2147)), _last_agent=Agent(name='MathAgent', handoff_description=None, tools=[], mcp_servers=[], mcp_config={}, instructions='You are a helpful math assistant.', prompt=None, handoffs=[], model=<agents.models.openai_chatcompletions.OpenAIChatCompletionsModel object at 0x78430578a890>, model_settings=ModelSettings(temperature=None, top_p=None, frequency_penalty=None, presence_penalty=None, tool_choice=None, parallel_tool_calls=None, truncation=None, max_tokens=None, reasoning=None, metadata=None, store=None, include_usage=None, response_include=None, extra_query=None, extra_body=None, extra_headers=None, extra_args=None), input_guardrails=[], output_guardrails=[], output_type=None, hooks=None, tool_use_behavior='run_llm_again', reset_tool_choice=True))"
            ]
          },
          "execution_count": 21,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "result"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1m8xnCs4KKG5"
      },
      "source": [
        "# 💬 Step 3: Running Agent Asynchronously"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "jZA-iSR9KMJ9",
        "outputId": "a88992a8-ea32-4531-cdbf-27d30afc5ba1"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Recursion in programming is a powerful concept where a function calls itself, directly or indirectly, to solve a problem. Think of it as defining something in terms of itself, but with a built-in \"stop\" condition.\n",
            "\n",
            "To understand recursion, you need to grasp two main components:\n",
            "\n",
            "1.  **Base Case:** This is the essential condition that stops the recursion. Without a base case, the function would call itself indefinitely, leading to an infinite loop (and eventually a \"stack overflow\" error). The base case provides a direct answer for the simplest version of the problem.\n",
            "2.  **Recursive Step:** This is the part where the function calls itself with a modified (usually smaller or simpler) input. The idea is that you break down the problem into smaller, similar subproblems until you reach the base case.\n",
            "\n",
            "### How Recursion Works (Under the Hood): The Call Stack\n",
            "\n",
            "When a function is called, the computer allocates a block of memory on something called the **call stack**. This block, known as a **stack frame**, stores information about that function call (its local variables, parameters, and the point in the code to return to after the function finishes).\n",
            "\n",
            "When a recursive function calls itself, a new stack frame is pushed onto the stack for each call. This continues until the base case is reached. Once the base case returns a value, the stack frames start to \"unwind\" one by one. Each function call finishes its execution using the return value from the call beneath it, until the very first call completes and returns the final result.\n",
            "\n",
            "### Analogy: Matryoshka Dolls (Russian Nesting Dolls)\n",
            "\n",
            "Imagine you have a set of Matryoshka dolls.\n",
            "*   **The Problem:** Find the smallest doll inside.\n",
            "*   **Recursive Step:** If the doll in your hand isn't the smallest, open it.\n",
            "*   **Base Case:** If the doll you're holding *is* the smallest (you can't open it further), you've found your answer.\n",
            "\n",
            "You keep opening dolls (recursive step) until you hit the smallest one (base case). Then you know the answer for that doll, and you can close up the larger dolls, one by one, until you've closed all of them, having found the smallest.\n",
            "\n",
            "### When to Use Recursion (Advantages):\n",
            "\n",
            "1.  **Elegance and Readability:** For problems that are naturally self-similar or can be defined in terms of smaller versions of themselves, recursive solutions can be very clean, intuitive, and concise.\n",
            "2.  **Solving Specific Problem Types:**\n",
            "    *   **Tree and Graph Traversal:** Many algorithms for traversing data structures like trees (e.g., depth-first search, in-order/pre-order/post-order traversals) are inherently recursive.\n",
            "    *   **Divide and Conquer Algorithms:** Algorithms like Merge Sort, Quick Sort, and binary search break a problem into smaller subproblems, solve them recursively, and then combine the results.\n",
            "    *   **Fractals:** Generating fractals is often done recursively.\n",
            "\n",
            "### When Not to Use Recursion (Disadvantages and Considerations):\n",
            "\n",
            "1.  **Performance Overhead:** Each function call has some overhead (managing the call stack, saving/restoring registers). For simple problems, an iterative (loop-based) solution is often faster and more memory-efficient.\n",
            "2.  **Memory Usage (Stack Overflow):** If the recursion goes too deep (too many nested calls), it can exhaust the available memory on the call stack, leading to a \"Stack Overflow Error.\" This is common if the base case is not reachable or the problem size is too large for the recursion depth.\n",
            "3.  **Debugging:** Tracing the execution flow of recursive functions can be more challenging than iterative ones, as you're jumping in and out of the same function.\n",
            "4.  **Tail Recursion Optimization (Advanced):** Some compilers and interpreters can optimize a specific type of recursion called \"tail recursion\" to behave more like an iteration, reducing the stack overhead. However, not all languages or environments support this.\n",
            "\n",
            "### Example: Calculating Factorial\n",
            "\n",
            "The factorial of a non-negative integer `n`, denoted `n!`, is the product of all positive integers less than or equal to `n`.\n",
            "*   `5! = 5 * 4 * 3 * 2 * 1 = 120`\n",
            "*   `0! = 1` (by definition, this is our base case)\n",
            "\n",
            "Notice that `5! = 5 * (4!)`, and `4! = 4 * (3!)`, and so on. This shows the recursive nature.\n",
            "\n",
            "**Recursive Function in Python:**\n",
            "\n",
            "```python\n",
            "def factorial(n):\n",
            "    # 1. Base Case:\n",
            "    if n == 0:\n",
            "        return 1\n",
            "    # 2. Recursive Step:\n",
            "    else:\n",
            "        return n * factorial(n - 1)\n",
            "\n",
            "# Let's trace factorial(3):\n",
            "# factorial(3)\n",
            "#   -> return 3 * factorial(2)\n",
            "#                   -> return 2 * factorial(1)\n",
            "#                                   -> return 1 * factorial(0)\n",
            "#                                                   -> return 1 (Base case reached!)\n",
            "#                                   -> returns 1 * 1 = 1\n",
            "#                   -> returns 2 * 1 = 2\n",
            "#   -> returns 3 * 2 = 6\n",
            "\n",
            "print(factorial(5))  # Output: 120\n",
            "print(factorial(0))  # Output: 1\n",
            "# print(factorial(-1)) # This would lead to infinite recursion and a Stack Overflow!\n",
            "```\n",
            "\n",
            "### In Summary:\n",
            "\n",
            "Recursion is a powerful and elegant technique for solving problems that can be broken down into smaller, self-similar subproblems. It's crucial to always define a clear **base case** to prevent infinite loops. While it offers readability and simplicity for certain problem domains, be mindful of its potential performance and memory overhead compared to iterative solutions.\n"
          ]
        }
      ],
      "source": [
        "import asyncio\n",
        "\n",
        "async def main():\n",
        "\n",
        "    result: Runner = await Runner.run(math_agent, \"Tell me about recursion in programming.\")\n",
        "\n",
        "    print(result.final_output)\n",
        "\n",
        "\n",
        "asyncio.run(main())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7RKgPtw2XlJs"
      },
      "source": [
        "## Example 1:\n",
        "### 👨‍🍳🍽️ Recipe Bot"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "id": "0LzWsFBvapjz"
      },
      "outputs": [],
      "source": [
        "set_tracing_disabled(disabled=True)\n",
        "\n",
        "# Client Setup for Connecting to Gemini\n",
        "external_client:AsyncOpenAI = AsyncOpenAI(\n",
        "    api_key=gemini_api_key,\n",
        "    base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n",
        ")\n",
        "\n",
        "#Initialize model\n",
        "model:OpenAIChatCompletionsModel = OpenAIChatCompletionsModel(\n",
        "    model=\"gemini-2.5-flash\",\n",
        "    openai_client=external_client\n",
        ")\n",
        "\n",
        "def main():\n",
        "  # Create the Recipe Agent\n",
        "  agent = Agent(\n",
        "      name=\"RecipeBot\",\n",
        "      instructions=(\n",
        "          \"\"\"You are a helpful recipe assistant. A user will give you a few ingredients\n",
        "          they have at home, and you will suggest one simple and quick recipe using only those items.\n",
        "          Keep it short, step-by-step, and easy for beginners to cook.\"\"\"\n",
        "      ),\n",
        "      model=model\n",
        "  )\n",
        "\n",
        "  print(\"\\n🍳 What can I cook today?\\n\")\n",
        "  ingredients = \"eggs, tomatoes, onions, and bread\"\n",
        "  result:Runner = Runner.run_sync(agent, f\"I have these at home: {ingredients}. What can I cook?\")\n",
        "\n",
        "  print(result.final_output)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "DyfXjUXsawYr",
        "outputId": "13641075-1daf-4798-ee16-07453304428c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "🍳 What can I cook today?\n",
            "\n",
            "Here's a quick and simple recipe for you:\n",
            "\n",
            "**Tomato & Onion Scramble on Toast**\n",
            "\n",
            "This recipe makes 1 serving.\n",
            "\n",
            "**You'll need:**\n",
            "*   2 eggs\n",
            "*   1/4 onion\n",
            "*   1/2 tomato\n",
            "*   2 slices bread\n",
            "*   A little cooking oil or butter (optional, but recommended)\n",
            "*   Salt and pepper (optional, but recommended)\n",
            "\n",
            "**Steps:**\n",
            "\n",
            "1.  **Prep:** Dice the onion finely. Dice the tomato into small pieces.\n",
            "2.  **Sauté Veggies:** Heat a small pan over medium heat. Add a tiny bit of oil or butter if you have it. Add the diced onion and cook for 2-3 minutes until it starts to soften. Then add the diced tomato and cook for another 1-2 minutes until slightly tender.\n",
            "3.  **Scramble Eggs:** While the veggies cook, crack your eggs into a bowl, add a pinch of salt and pepper (if using), and whisk them lightly with a fork. Pour the whisked eggs into the pan with the cooked vegetables.\n",
            "4.  **Cook & Toast:** Let the eggs set for a few seconds, then gently push and fold them with a spatula until they are cooked to your liking (soft scrambled). At the same time, pop your bread into a toaster or toast it in another pan until golden.\n",
            "5.  **Serve:** Spoon the egg and vegetable mixture onto your toasted bread. Enjoy!\n"
          ]
        }
      ],
      "source": [
        "if __name__ == \"__main__\":\n",
        "    main()"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
